#ifndef HISTOGRAM_PTR_H
#define HISTOGRAM_PTR_H

class Counter;
//p->m == (*p).m == p[0].m
template< typename T> class Ptr
{
public:
    Ptr(T* ptr):_ptr(ptr)
    {
        _counter = new Counter();
        _counter->inc();
    }

    ~Ptr()
    {
        if(_counter->dec())
        {
            delete[] _ptr;
            delete _counter;
        }
    }

    Ptr(const Ptr<T>& other):_counter(other._counter),_ptr(other._ptr)
    {
        _counter->inc();
    }

    Ptr<T>& operator= (const Ptr<T>& other)
    {
        if (&other == this) return *this;

        if(_counter->dec())
        {
            delete[] _ptr;
            delete _counter;
        }
        _ptr = other._ptr;
        _counter = other._counter;
        _counter->inc();
        return *this;
    }

    T* operator->(){return _ptr;}
    T& operator*(){return *_ptr;}
    T& operator[](int i){return _ptr[i];}


private:
    T* _ptr;
    Counter* _counter;
};

class Counter
{
public:
    Counter():_refs(0){}
    void inc(){_refs++;}
    bool dec(){return (--_refs)==0;}
private:
    int _refs;
};

#endif
